package com.gitee.wsl.platform.network

import com.gitee.wsl.platform.network.utils.IfaddrsInteractor
import com.gitee.wsl.platform.network.utils.IfaddrsInteractorImpl
import com.gitee.wsl.platform.network.utils.NWPathMonitorNetworkMonitor
import com.gitee.wsl.platform.network.utils.NetworkMonitor
import com.gitee.wsl.platform.network.utils.SCNetworkReachabilityNetworkMonitor
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.useContents
import platform.Foundation.NSProcessInfo

@OptIn(ExperimentalForeignApi::class)
private fun isVersionOrLater(major: Int, minor: Int = 0, patch: Int = 0): Boolean =
    NSProcessInfo.processInfo.operatingSystemVersion.useContents {
        when {
            majorVersion.toInt() > major -> true
            majorVersion.toInt() == major && minorVersion.toInt() > minor -> true
            majorVersion.toInt() == major && minorVersion.toInt() == minor && patchVersion.toInt() >= patch -> true
            else -> false
        }
    }


actual suspend fun NetworkChecker.getInfo(): ConnectionInfo? {
    val networkConnection = getNetworkStatus()
    if(!networkConnection.isConnected) return null
    val networkType = networkConnection.networkType

    val ifaddrsInteractor: IfaddrsInteractor = IfaddrsInteractorImpl()

    // need to be an `internal var` to allow unit tests
    val networkMonitor: NetworkMonitor = if (isVersionOrLater(12)) {
        NWPathMonitorNetworkMonitor()
    } else {
        SCNetworkReachabilityNetworkMonitor()
    }

    val networkInterfaces = networkMonitor.getCurrentNetworkInterfaceNames() ?: return null

    val ifAddresses = ifaddrsInteractor.get(networkInterfaces)

    return ConnectionInfo(
        ipv4 = ifAddresses.afInet,
        ipv6 = ifAddresses.afInet6,
        //externalIp = getExternalIp()
    )
}